/**
存放数据的队列
*/

typedef struct PacketList {
	AVPacket pkt;
	struct PacketList *next;
}PacketList;


class PacketQueue {
	public:
		PacketQueue();

		virtual ~PacketQueue();
		
		int pushPacket(AVPacket *pkt);

		int pushNullPacket();

		void flush();
		//终止
		void abort();

		void start();
		//获取数据包
		int getPacket(AVPacket *pkt);
		int getPacket(AVPacket *pkt, int block);

		int getPacketSize();

		int getSize();

		int64_t getDuration();

		int isAbort();

	private:
		int put(AVPacket *pkt);

	private:
		Mutex mMutex;
		Condition mCondition;
		PacketList *first_pkt, *last_pkt;
		int nb_packets;
		int size;
		int64_t duration;
		int abort_request;
};

PacketQueue::PacketQueue() {
	abort_request = 0;
	first_pkt = NULL;
	last_pkt = NULL;
	nb_packets = 0;
	size = 0;
	duration = 0;
}

PacketQueue::~PacketQueue() {
	abort();
	flush();
}

int PacketQueue::put(AVPacket *pkt) {
	if(abort_request){
		return -1;
	}

	PacketList *pl;
	pl = (PacketList*)av_malloc(sizeof(PacketList));
	if(!pl){
		return -1;
	}
	pl->next = NULL;
	pl->pkt = *pkt;

	if(!last_pkt){
		firtst_pkt = pl;
	}else{
		last_pkt->next = pl;
	}
	last_pkt = pl;
	nb_packets++;
	size += pl->pkt.size(); + sizeof(*pl);
	duration += pl->pkt.duration();
	return 0;
}

int PacketQueue::pushPacket(AVPacket *pkt) {
	int ret;
	mMutex.lock();
	ret = put(pkt);
	mCondition.signal();
	mMutex.unlock();
	//AVPAcket动态生成的，调用av_packet_unref使Packet变得无效 释放
	if(ret < 0){
		av_packet_unref(pkt);
	}
	return ret;
}

int PacketQueue::pushNullPacket(int streamIndex) {
	AVPacket *pkt, pkt1;
	pkt = &pkt1;
	av_init_packet(pkt);
	pkt->data = NULL;
	pkt->size = 0;
	pkt->streamIndex = streamIndex;
	return pushPacket(pkt);
}

//刷新数据包
void PacketQueue::flush() {
	PacketList *pkt, *pkt1;

	mMutex.lock();
	for(pkt=first_pkt; pkt; pkt=pkt1){
		pkt1 = pkt->next;
		av_packet_unref(&pkt->pkt);
		av_freep(&pkt);
	}
	first_pkt = NULL;
	last_pkt = NULL;
	size = 0;
	nb_packets = 0;
	duration = 0;
	mCondition.signal();
	mMutex.unlock();
}

//终止队列
void PacketQueue::abort() {
	mMutex.lock();
	abort_request = 1;
	mCondition.signal();
	mMutex.unlock();
}

void PacketQueue::start() {
	mMutex.lock();
	abort_request = 0;
	mCondition.signal();
	mMutex.unlock();
}


int PacketQueue::getPacket(AVPacket *pkt) {
	return getPacket(pkt, 1);
}

//取数据包 block其实就是包的顺序，正常取走first，如果为空则wait等待
int PacketQueue::getPacket(AVPacket *pkt, int block) {
	AVPacketList *pktl;
	int ret;

	mMutex.lock();
	//循环等待队列
	for(;;){
		if(abort_request){
			ret = -1;
			break;
		}

		pktl = first_pkt;
		if(pktl){
			first_pkt = pktl->next;
			if(!first_pkt){
				last_pkt = NULL;
			}
			nb_packets--;
			size -= pktl->pkt.size + sizeof(*pktl);
			duration -= pktl->pkt.duration;
			*pkt = pktl->pkt;
			av_free(pktl);
			ret = 1;
			break;
		}else if(!block){
			ret = 0;
			break;
		}else{
			mCondition.wait();
		}
	}
	mMutex.unlock();
	return ret;
}

int PacketQueue::getPacketSize() {
	Mutex:Autolock lock(mMutex);
	return nb_packets;
}

int PacketQueue::getSize() {
	return size;
}

int PacketQueue::isAbort() {
	return abort_request;
}
